home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / worn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  8.7 KB  |  338 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)worn.c    3.1    93/06/24    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. static void FDECL(rel_1_obj, (struct monst *,struct obj *));
  8.  
  9. const struct worn {
  10.     long w_mask;
  11.     struct obj **w_obj;
  12. } worn[] = {
  13.     { W_ARM, &uarm },
  14.     { W_ARMC, &uarmc },
  15.     { W_ARMH, &uarmh },
  16.     { W_ARMS, &uarms },
  17.     { W_ARMG, &uarmg },
  18.     { W_ARMF, &uarmf },
  19. #ifdef TOURIST
  20.     { W_ARMU, &uarmu },
  21. #endif
  22.     { W_RINGL, &uleft },
  23.     { W_RINGR, &uright },
  24.     { W_WEP, &uwep },
  25.     { W_AMUL, &uamul },
  26.     { W_TOOL, &ublindf },
  27.     { W_BALL, &uball },
  28.     { W_CHAIN, &uchain },
  29.     { 0, 0 }
  30. };
  31.  
  32. void
  33. setworn(obj, mask)
  34. register struct obj *obj;
  35. long mask;
  36. {
  37.     register const struct worn *wp;
  38.     register struct obj *oobj;
  39.  
  40.     for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
  41.         oobj = *(wp->w_obj);
  42.         if(oobj && !(oobj->owornmask & wp->w_mask))
  43.             impossible("Setworn: mask = %ld.", wp->w_mask);
  44.         if(oobj) {
  45.             oobj->owornmask &= ~wp->w_mask;
  46.             /* leave as "x = x <op> y", here and below, for broken
  47.              * compilers */
  48.             u.uprops[objects[oobj->otyp].oc_oprop].p_flgs = 
  49.                 u.uprops[objects[oobj->otyp].oc_oprop].p_flgs & 
  50.                 ~wp->w_mask;
  51.             if (oobj->oartifact) set_artifact_intrinsic(oobj, 0, mask);
  52.         }
  53.         *(wp->w_obj) = obj;
  54.         if(obj) {
  55.             obj->owornmask |= wp->w_mask;
  56.         /* prevent getting intrinsics from wielding potions, etc... */
  57.         /* wp_mask should be same as mask at this point */
  58.             if(obj->oclass == WEAPON_CLASS || mask != W_WEP) {
  59.             u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  60.                 u.uprops[objects[obj->otyp].oc_oprop].p_flgs | 
  61.                 wp->w_mask;
  62.             if (obj->oartifact) set_artifact_intrinsic(obj,1,mask);
  63.             } else if(obj->oartifact)
  64.             set_artifact_intrinsic(obj,1,mask);
  65.         }
  66.     }
  67. }
  68.  
  69. /* called e.g. when obj is destroyed */
  70. void
  71. setnotworn(obj)
  72. register struct obj *obj;
  73. {
  74.     register const struct worn *wp;
  75.  
  76.     if (!obj) return;
  77.     for(wp = worn; wp->w_mask; wp++)
  78.         if(obj == *(wp->w_obj)) {
  79.             *(wp->w_obj) = 0;
  80.             u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  81.                 u.uprops[objects[obj->otyp].oc_oprop].p_flgs & 
  82.                     ~wp->w_mask;
  83.             obj->owornmask &= ~wp->w_mask;
  84.             if (obj->oartifact)
  85.                 set_artifact_intrinsic(obj, 0, wp->w_mask);
  86.         }
  87. }
  88.  
  89. #ifdef MUSE
  90. int
  91. find_mac(mon)
  92. register struct monst *mon;
  93. {
  94.     register struct obj *obj;
  95.     int base = mon->data->ac;
  96.     long mwflags = mon->misc_worn_check;
  97.  
  98.     for(obj = mon->minvent; obj; obj = obj->nobj) {
  99.         if (obj->owornmask & mwflags)
  100.             base -= ARM_BONUS(obj);
  101.     }
  102.     return base;
  103. }
  104.  
  105. /* Wear first object of that type it finds, and never switch unless it
  106.  * has none at all.  This means that monsters with leather armor never
  107.  * switch to plate mail, but it also avoids the overhead of either having 8
  108.  * struct obj *s for every monster in the game, or of doing multiple inventory
  109.  * searches each round using which_armor().
  110.  */
  111. void
  112. m_dowear(mon, creation)
  113. register struct monst *mon;
  114. boolean creation;
  115. {
  116.     register struct obj *obj;
  117.  
  118.     /* Note the restrictions here are the same as in dowear in do_wear.c
  119.      * except for the additional restriction on intelligence.  (Players
  120.      * are always intelligent, even if polymorphed).
  121.      */
  122.     if (verysmall(mon->data) || nohands(mon->data)) return;
  123.     if (is_animal(mon->data) || mindless(mon->data)) return;
  124.  
  125.     for(obj = mon->minvent; obj; obj = obj->nobj) {
  126.         long flag;
  127.  
  128.         if (obj->otyp == AMULET_OF_LIFE_SAVING ||
  129.                 obj->otyp == AMULET_OF_REFLECTION)
  130.             flag = W_AMUL;
  131. # ifdef TOURIST
  132.         else if (obj->otyp == HAWAIIAN_SHIRT) flag = W_ARMU;
  133. # endif
  134.         else if (is_cloak(obj)) {
  135.             if (cantweararm(mon->data))
  136.                 continue;
  137.             flag = W_ARMC;
  138.         } else if (is_helmet(obj)) flag = W_ARMH;
  139.         else if (is_shield(obj)) {
  140.             if (MON_WEP(mon) && bimanual(MON_WEP(mon)))
  141.                 continue;
  142.             flag = W_ARMS;
  143.         } else if (is_gloves(obj)) {
  144.             if (MON_WEP(mon) && MON_WEP(mon)->cursed)
  145.                 continue;
  146.             flag = W_ARMG;
  147.         } else if (is_boots(obj)) {
  148.             if (slithy(mon->data) || mon->data->mlet == S_CENTAUR)
  149.                 continue;
  150.             flag = W_ARMF;
  151.         } else if (obj->oclass == ARMOR_CLASS) {
  152.             if (cantweararm(mon->data))
  153.                 continue;
  154.             flag = W_ARM;
  155.         } else continue;
  156.         if (mon->misc_worn_check & flag) continue;
  157.             /* already wearing one */
  158.         if (!creation && canseemon(mon)) {
  159.             pline("%s puts on %s.", Monnam(mon),
  160.                         distant_name(obj, doname));
  161.             mon->mfrozen = objects[obj->otyp].oc_delay;
  162.             if (mon->mfrozen) mon->mcanmove = 0;
  163.         }
  164.         mon->misc_worn_check |= flag;
  165.         obj->owornmask |= flag;
  166.     }
  167. }
  168.  
  169. struct obj *
  170. which_armor(mon, flag)
  171. struct monst *mon;
  172. long flag;
  173. {
  174.     register struct obj *obj;
  175.  
  176.     for(obj = mon->minvent; obj; obj = obj->nobj)
  177.         if (obj->owornmask & flag) return obj;
  178.     return((struct obj *)0);
  179. }
  180.  
  181. static void
  182. rel_1_obj(mon, obj)
  183. struct monst *mon;
  184. struct obj *obj;
  185. {
  186.     struct obj *otmp;
  187.     struct obj *backobj = (struct obj *)0;
  188.  
  189.     for(otmp = mon->minvent; otmp; otmp = otmp->nobj) {
  190.         if (obj == otmp) {
  191.             if (!backobj) mon->minvent = otmp->nobj;
  192.             else backobj->nobj = otmp->nobj;
  193.             place_object(otmp, mon->mx, mon->my);
  194.             otmp->nobj = fobj;
  195.             fobj = otmp;
  196.             if (cansee(mon->mx, mon->my)) newsym(mon->mx, mon->my);
  197.             return;
  198.         }
  199.         backobj = otmp;
  200.     }
  201.     impossible("%s has %s missing?", Monnam(mon), xname(obj));
  202. }
  203.  
  204. void
  205. mon_break_armor(mon)
  206. struct monst *mon;
  207. {
  208.     register struct obj *otmp;
  209.     struct permonst *mdat = mon->data;
  210.     boolean vis = cansee(mon->mx, mon->my);
  211.     const char *pronoun = him[pronoun_gender(mon)],
  212.             *ppronoun = his[pronoun_gender(mon)];
  213.  
  214.     if (breakarm(mdat)) {
  215.         if ((otmp = which_armor(mon, W_ARM)) != 0) {
  216.         if (vis)
  217.             pline("%s breaks out of %s armor!", Monnam(mon), ppronoun);
  218.         else
  219.             You("hear a cracking sound.");
  220.         mon->misc_worn_check &= ~W_ARM;
  221.         m_useup(mon, otmp);
  222.         }
  223.         if ((otmp = which_armor(mon, W_ARMC)) != 0) {
  224.         if (otmp->oartifact) {
  225.             if (vis)
  226.             pline("%s cloak falls off!", s_suffix(Monnam(mon)));
  227.             mon->misc_worn_check &= ~W_ARMC;
  228.             otmp->owornmask &= ~W_ARMC;
  229.             rel_1_obj(mon, otmp);
  230.         } else {
  231.             if (vis)
  232.             pline("%s cloak tears apart!", s_suffix(Monnam(mon)));
  233.             else
  234.             You("hear a ripping sound.");
  235.             mon->misc_worn_check &= ~W_ARMC;
  236.             m_useup(mon, otmp);
  237.         }
  238.         }
  239. # ifdef TOURIST
  240.         if ((otmp = which_armor(mon, W_ARMU)) != 0) {
  241.         if (vis)
  242.             pline("%s shirt rips to shreds!", s_suffix(Monnam(mon)));
  243.         else
  244.             You("hear a ripping sound.");
  245.         mon->misc_worn_check &= ~W_ARMU;
  246.         m_useup(mon, otmp);
  247.         }
  248. # endif
  249.         } else if (sliparm(mdat)) {
  250.         if ((otmp = which_armor(mon, W_ARM)) != 0) {
  251.         if (vis)
  252.             pline("%s armor falls around %s!", 
  253.                      s_suffix(Monnam(mon)), pronoun);
  254.         else
  255.             You("hear a thud.");
  256.         mon->misc_worn_check &= ~W_ARM;
  257.         otmp->owornmask &= ~W_ARM;
  258.         rel_1_obj(mon, otmp);
  259.         }
  260.         if ((otmp = which_armor(mon, W_ARMC)) != 0) {
  261.         if (vis)
  262.             if (is_whirly(mon->data))
  263.             pline("%s cloak falls, unsupported!", 
  264.                          s_suffix(Monnam(mon)));
  265.             else
  266.             pline("%s shrinks out of %s cloak!", Monnam(mon),
  267.                                 ppronoun);
  268.         mon->misc_worn_check &= ~W_ARMC;
  269.         otmp->owornmask &= ~W_ARMC;
  270.         rel_1_obj(mon, otmp);
  271.         }
  272. # ifdef TOURIST
  273.         if ((otmp = which_armor(mon, W_ARMU)) != 0) {
  274.         if (vis)
  275.             if (sliparm(mon->data))
  276.             pline("%s seeps right through %s shirt!",
  277.                     Monnam(mon), ppronoun);
  278.             else
  279.             pline("%s becomes much too small for %s shirt!",
  280.                     Monnam(mon), ppronoun);
  281.         mon->misc_worn_check &= ~W_ARMU;
  282.         otmp->owornmask &= ~W_ARMU;
  283.         rel_1_obj(mon, otmp);
  284.         }
  285. # endif
  286.     }
  287.     if (nohands(mdat) || verysmall(mdat)) {
  288.         if ((otmp = which_armor(mon, W_ARMG)) != 0) {
  289.         if (vis)
  290.             pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
  291.                     MON_WEP(mon) ? " and weapon" : "");
  292.         possibly_unwield(mon);
  293.         mon->misc_worn_check &= ~W_ARMG;
  294.         otmp->owornmask &= ~W_ARMG;
  295.         rel_1_obj(mon, otmp);
  296.         }
  297.         if ((otmp = which_armor(mon, W_ARMS)) != 0) {
  298.         if (vis)
  299.             pline("%s can no longer hold %s shield!", Monnam(mon),
  300.                                 ppronoun);
  301.         else
  302.             You("hear a clank.");
  303.         mon->misc_worn_check &= ~W_ARMS;
  304.         otmp->owornmask &= ~W_ARMS;
  305.         rel_1_obj(mon, otmp);
  306.         }
  307.         if ((otmp = which_armor(mon, W_ARMH)) != 0) {
  308.         if (vis)
  309.             pline("%s helmet falls to the %s!", 
  310.               s_suffix(Monnam(mon)), surface(mon->mx, mon->my));
  311.         else
  312.             You("hear a clank.");
  313.         mon->misc_worn_check &= ~W_ARMH;
  314.         otmp->owornmask &= ~W_ARMH;
  315.         rel_1_obj(mon, otmp);
  316.         }
  317.     }
  318.     if (nohands(mdat) || verysmall(mdat) || slithy(mdat) ||
  319.         mdat->mlet == S_CENTAUR) {
  320.         if ((otmp = which_armor(mon, W_ARMF)) != 0) {
  321.         if (vis) {
  322.             if (is_whirly(mon->data))
  323.             pline("%s boots fall away!", 
  324.                            s_suffix(Monnam(mon)));
  325.             else pline("%s boots %s off %s feet!", 
  326.             s_suffix(Monnam(mon)),
  327.             verysmall(mdat) ? "slide" : "are pushed", ppronoun);
  328.         }
  329.         mon->misc_worn_check &= ~W_ARMF;
  330.         otmp->owornmask &= ~W_ARMF;
  331.         rel_1_obj(mon, otmp);
  332.         }
  333.     }
  334. }
  335. #endif
  336.  
  337. /*worn.c*/
  338.